package com.stox.client.ui.javafx.chartingy.event.listener;

import javafx.geometry.Point2D;
import javafx.scene.input.MouseEvent;

import com.stox.client.ui.javafx.chartingy.model.chart.Chart;
import com.stox.client.ui.javafx.chartingy.view.ChartingView;
import com.stox.client.ui.javafx.chartingy.widget.MouseZoomIndicator;
import com.stox.client.ui.javafx.widget.RangeSlider;
import com.stox.shared.model.intf.Callback;
import com.stox.shared.util.MathUtil;

public class ZoomMouseEventStrategy implements ChartingMouseEventStrategy {

	private Callback<Void, Void> completionCallback;
	private MouseZoomIndicator indicator;

	@Override
	public void setCompletionCallback(final Callback<Void, Void> completionCallbak) {
		completionCallback = completionCallbak;
	}


	@Override
	public void handle(final MouseEvent event) {
		if (MouseEvent.MOUSE_PRESSED.equals(event.getEventType())) {
			final ChartingView chartingView = (ChartingView) event.getSource();
			final Chart<?, ?> chart = chartingView.resolveChart(event.getSceneX(), event.getSceneY());
			if (null != chart) {
				indicator = new MouseZoomIndicator(chart);
				chart.getChildren().add(indicator);
				final Point2D point = chart.getChartContentArea().sceneToLocal(event.getSceneX(), event.getSceneY());
				indicator.setLayoutX(point.getX());
				indicator.setWidth(1);
				event.consume();
			}
		} else if (MouseEvent.MOUSE_DRAGGED.equals(event.getEventType())) {
			if (null != indicator) {
				final Chart<?, ?> chart = indicator.getChart();
				final double x = chart.getChartContentArea().sceneToLocal(event.getSceneX(), event.getSceneY()).getX();
				indicator.setWidth(x < indicator.getLayoutX() ? (indicator.getLayoutX() + indicator.getWidth()) - x : x - indicator.getLayoutX());
				indicator.setLayoutX(x < indicator.getLayoutX() ? x : indicator.getLayoutX());
				event.consume();
			}
		} else if (MouseEvent.MOUSE_RELEASED.equals(event.getEventType())) {
			if (null != indicator) {
				final Chart<?, ?> chart = indicator.getChart();
				final RangeSlider rangeSlieder = chart.getChartingView().getRangeSlider();
				final double lowValue = MathUtil.praportion(chart.getChartContentArea().getLayoutX(), indicator.getLayoutX(), chart.getChartContentArea().getLayoutX() + chart.getChartContentArea().getWidth(), rangeSlieder.getLowValue(), rangeSlieder.getHighValue());
				final double highValue = MathUtil.praportion(chart.getChartContentArea().getLayoutX(), indicator.getLayoutX() + indicator.getWidth(), chart.getChartContentArea().getLayoutX() + chart.getChartContentArea().getWidth(), rangeSlieder.getLowValue(), rangeSlieder.getHighValue());
				rangeSlieder.setHighValueChanging(true);
				rangeSlieder.setLowValue(lowValue);
				rangeSlieder.setHighValue(highValue);
				rangeSlieder.setHighValueChanging(false);
				chart.getChildren().remove(indicator);
			}
			completionCallback.execute(null);
			event.consume();
		}
	}

	@Override
	public void attach(final ChartingView chartingView) {
		chartingView.addEventFilter(MouseEvent.MOUSE_PRESSED, this);
		chartingView.addEventFilter(MouseEvent.MOUSE_DRAGGED, this);
		chartingView.addEventFilter(MouseEvent.MOUSE_RELEASED, this);
	}

	@Override
	public void detach(final ChartingView chartingView) {
		chartingView.removeEventFilter(MouseEvent.MOUSE_PRESSED, this);
		chartingView.removeEventFilter(MouseEvent.MOUSE_DRAGGED, this);
		chartingView.removeEventFilter(MouseEvent.MOUSE_RELEASED, this);
	}

}
